package com.hahaliu.hahaliu.service.impl.video;

import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hahaliu.hahaliu.common.exception.BaseException;
import com.hahaliu.hahaliu.common.utils.RedisUtil;
import com.hahaliu.hahaliu.mapper.FavoriteMapper;
import com.hahaliu.hahaliu.mapper.VideoMapper;
import com.hahaliu.hahaliu.pojo.entity.Favorite;
import com.hahaliu.hahaliu.pojo.entity.Video;
import com.hahaliu.hahaliu.service.video.FavoriteService;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
* @author Liubuzhu
* @description 针对表【favorite】的数据库操作Service实现
* @createDate 2024-06-13 08:30:21
*/
@Service
public class FavoriteServiceImpl extends ServiceImpl<FavoriteMapper, Favorite>
    implements FavoriteService{
	@Autowired
	private FavoriteMapper favoriteMapper;

	@Autowired
	private RedisUtil redisUtil;

	@Autowired
	private VideoMapper videoMapper;

	@Autowired
	private SqlSessionFactory sqlSessionFactory;

	@Autowired
	@Qualifier("taskExecutor")
	private Executor taskExecutor;

	public List<Favorite> getFavoriteList(Integer uid, boolean isOwner) {
		String key = "favorites:" + uid;   // uid用户的收藏夹列表
		// 从Redis获取收藏夹数据
		String string = redisUtil.getObjectString(key);
		List<Favorite> list = JSONArray.parseArray(string, Favorite.class);

		if (list != null) {
			// 如果是非拥有者，过滤出可见的收藏夹
			if (!isOwner) {
				return list.stream()
						.filter(favorite -> favorite.getVisible() == 1)
						.collect(Collectors.toList());
			}
			return list;
		}

		// 若Redis没有数据，从数据库查询
		QueryWrapper<Favorite> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("u_id", uid)
				.ne("is_delete", 1)
				.orderByDesc("f_id");
		list = favoriteMapper.selectList(queryWrapper);

		// 如果查询结果为空，返回空列表
		if (list == null || list.isEmpty()) {
			return Collections.emptyList();
		}

		// 使用事务批量操作，减少数据库连接的开销
		try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
			// 设置收藏夹封面
			list.forEach(favorite -> {
				if (favorite.getCover() == null) {
					Set<Object> set = redisUtil.zReverange("favorite_video:" + favorite.getFId(), 0, 0);
					if (set != null && !set.isEmpty()) {
						Integer vid = (Integer) set.iterator().next();
						Video video = videoMapper.selectById(vid);
						if (video != null) {
							favorite.setCover(video.getCoverUrl());
						}
					}
				}
			});
			sqlSession.commit();
		}

		// 异步缓存更新，避免阻塞主线程
		List<Favorite> finalList = new ArrayList<>(list);  // 用于提交到异步任务的副本
		CompletableFuture.runAsync(() -> {
			redisUtil.setExObjectValue(key, finalList);
		}, taskExecutor);

		// 如果是非拥有者，过滤出可见的收藏夹
		if (!isOwner) {
			return list.stream()
					.filter(favorite -> favorite.getVisible() == 1)
					.collect(Collectors.toList());
		}

		return list;
	}

	public Favorite addFavorite(Integer uid, String title, String desc, Integer visible) {
		Favorite favorite = new Favorite(null, uid, 2, visible, null, title, desc, 0, LocalDateTime.now(), 0);
		favoriteMapper.insert(favorite);
		redisUtil.delValue("favorites:" + uid);
		return favorite;
	}

	public Favorite updateFavorite(Integer fid, Integer uid, String title, String desc, Integer visible) {
		Favorite favorite = favoriteMapper.selectById(fid);
		if (!Objects.equals(favorite.getUId(), uid)) {
			return null;
		}
		UpdateWrapper<Favorite> updateWrapper = new UpdateWrapper<>();
		updateWrapper.eq("f_id", fid).set("title", title).set("description", desc).set("visible", visible);
		favoriteMapper.update(null, updateWrapper);
		redisUtil.delValue("favorites:" + uid);
		return favorite;
	}

	public void deleteFavorite(Integer fid, Integer uid) {
//		// 1. 查询收藏夹，确保收藏夹存在并且当前用户是收藏夹的创建者
//		Favorite favorite = favoriteMapper.selectById(fid);
//		if (favorite == null) {
//			throw new RuntimeException("收藏夹不存在！");
//		}
//
//		if (!favorite.getUId().equals(uid)) {
//			throw new RuntimeException("无权限删除该收藏夹！");
//		}
//
//		// 2. 删除收藏夹中的所有视频
//		List<Integer> videoIds = favoriteMapper.getVideoIdsInFavorite(fid); // 获取该收藏夹中所有视频的ID
//
//		// 从数据库中删除收藏夹中的视频
//		if (!videoIds.isEmpty()) {
//			favoriteMapper.removeVideosFromFavorite(fid);
//		}
//
//		// 3. 检查每个视频是否仍然在其他收藏夹中，若没有，则设置为未收藏状态
//		for (Integer videoId : videoIds) {
//			// 查找该视频是否存在于其他收藏夹中
//			int count = favoriteMapper.countVideoInOtherFavorites(videoId, uid);
//			if (count == 0) {
//				// 如果该视频没有在其他收藏夹中，更新视频的收藏状态
//				videoMapper.updateFavoriteStatusToUnfavorited(videoId);
//			}
//		}
//
//		// 4. 删除收藏夹记录
//		favoriteMapper.deleteById(fid);
//
//		// 5. 更新 Redis 缓存
//		// 更新 Redis 中该用户的收藏夹数据
//		String key = "favorites:" + uid;
//		redisUtil.deleteKeysWithPrefix(key);  // 删除用户的收藏夹列表缓存
//
//		// 如果有其他方法获取更新后的收藏夹列表，可以重新缓存
//		List<Favorite> updatedFavorites = favoriteMapper.selectList(new QueryWrapper<Favorite>().eq("u_id", uid).ne("is_delete", 1));
//		redisUtil.setExObjectValue(key, updatedFavorites);  // 将更新后的收藏夹列表重新放入 Redis，并设置过期时间
	}

	public void cancelFavorite(Integer vid, Integer fid) {
		favoriteMapper.delete(new QueryWrapper<Favorite>().eq("v_id", vid).eq("f_id", fid));
	}

	@Override
	public List<Favorite> getFavorites(Integer uid, boolean isOwner) {
		String key = "favorites:" + uid;   // uid用户的收藏夹列表
		String string = redisUtil.getObjectString(key);
		List<Favorite> list = JSONArray.parseArray(string, Favorite.class);
		if (list != null) {
			if (!isOwner) {
				List<Favorite> list1 = new ArrayList<>();
				for (Favorite favorite : list) {
					if (favorite.getVisible() == 1) {
						list1.add(favorite);
					}
				}
				return list1;
			}
			return list;
		}
		QueryWrapper<Favorite> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("u_id", uid).ne("is_delete", 1).orderByDesc("f_id");
		list = favoriteMapper.selectList(queryWrapper);
		if (list != null && !list.isEmpty()) {
			// 使用事务批量操作 减少连接sql的开销
			try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
				// 设置收藏夹封面
				list.stream().parallel().forEach(favorite -> {
					if (favorite.getCover() == null) {
						Set<Object> set = redisUtil.zReverange("favorite_video:" + favorite.getFId(), 0, 0);    // 找到最近一个收藏的视频
						if (set != null && !set.isEmpty()) {
							Integer vid = (Integer) set.iterator().next();
							Video video = videoMapper.selectById(vid);
							favorite.setCover(video.getCoverUrl());
						}
					}
				});
				sqlSession.commit();
			}
			List<Favorite> finalList = list;
			CompletableFuture.runAsync(() -> {
				redisUtil.setExObjectValue(key, finalList);
			}, taskExecutor);
			if (!isOwner) {
				List<Favorite> list1 = new ArrayList<>();
				for (Favorite favorite : list) {
					if (favorite.getVisible() == 1) {
						list1.add(favorite);
					}
				}
				return list1;
			}
			return list;
		}
		return Collections.emptyList();
	}

}




